var arguments = process.argv.splice(2);
var param1 = arguments[0];
// console.log('param1:', param1)

//将字符串转化为json
const str2json = function(srcStr) {
	let json = JSON.parse(srcStr); // (new Function("return " + srcStr))(); // eval('(' + srcStr + ')'); // 
	return json;
}

//-----------------------------------------------------------------------------------------------------

//获取json长度
const getJsonLength = function (jsonData) {
    //return Object.keys(jsonData).length;
    var jsonLength = 0;
    for (var item in jsonData) {
        jsonLength++;
    }
    return jsonLength;
}

//获取类型
const getType = function (data) {
    if ("radio" == data.type) {
        return "单选";
    } else if ("checkbox" == data.type) {
        return "多选";
    } else if ("select" == data.type) {
        return "下拉选项";
    } else if ("text" == data.type) {
        return "文本框";
    } else if ("blanks" == data.type) {
        return "填空";//多项填空
    } else if ("textarea" == data.type) {
        return "文本框";
    } else if ("upload" == data.type) {
        return "文件上传";
    } else if ("star" == data.type) {
        return "量表";//NPS
    } else if ("sort" == data.type) {
        return "排序选择";
    } else if ("chained_selects" == data.type) {
        return "级联选择";//比如城市街道地址选择
    } else if ("datetime" == data.type) {
        return "文本框";
    } else if ("text_multiple" == data.type) {
        return "填空";
    } else if ("matrix_blank" == data.type) {
        return "矩阵填空";
    } else if ("matrix_radio" == data.type) {
        return "矩阵单选";
    } else if ("matrix_checkbox" == data.type) {
        return "矩阵多选";
    } else if ("matrix_star" == data.type) {
        return "矩阵量表";
    } else if ("description" == data.type) {
        return "占位题";//备注说明-文本描述
    } else {
        return "未知";
    }
}

//清洗文本
const cleanText = function (text) {
    let str = text.replace(/&lt;/g, "<").replace(/&gt;/g, ">");
    let tmp = str.replace(/<[^<>]*>/g, "");
    tmp = tmp.trim();//仅去除首尾空格 // tmp = tmp.replace(/\s/gim, "");//去除所有空白
    tmp = tmp.replace(/\{.*?\}/g, "");
    return tmp;
}

//构建矩阵选择题（单选，多选）选项
const buildMatrixChoise = function (data) {
    let inner = new Array();
    var subTitlesLength = getJsonLength(data.sub_titles);
    for (let k = 0; k < subTitlesLength; k++) {
        let line = data.sub_titles[k];
        let optLength = getJsonLength(data.options);
        for (let i = 1; i <= optLength; i++) {
            let tmpObj = new Object();
            tmpObj.title = cleanText(line.text) + "_" + data.options[i - 1].id + "_" + data.options[i - 1].text;//格式：行名_列id_列名
            tmpObj.optionId = line.id + "_" + data.options[i - 1].id + "_" + i;//格式：行ID_列ID_序号
            tmpObj.value = -1;
            inner.push(tmpObj);
        }
    }
    return inner;
}

//构建矩阵填空
const buildMatrixBlank = function (data) {
    let inner = new Array();
    var subTitlesLength = getJsonLength(data.sub_titles);
    for (let k = 0; k < subTitlesLength; k++) {
        let line = data.sub_titles[k];
        let blanksLength = getJsonLength(data.blanks);
        for (let i = 1; i <= blanksLength; i++) {
            let tmpObj = new Object();
            tmpObj.title = cleanText(line.text) + "_" + data.blanks[i - 1].blank_setting.id + "_" + data.blanks[i - 1].text;//格式：行名_列id_列名
            if (data.blanks[i - 1].blank_setting.required) {
                tmpObj.title += "_必填";
            }
            tmpObj.optionId = line.id + "_" + data.blanks[i - 1].blank_setting.id + "_" + i;//格式：行ID_列ID_序号
            tmpObj.value = -1;
            inner.push(tmpObj);
        }
    }
    return inner;
}

//通用匹配提取
const getMatchedStrs = function (str, reg) {
    return str.match(reg)[1];
}

//获取选项填空id
const getBlankId = function (text) {
    if (-1 != text.indexOf("data-id")) {
        return getMatchedStrs(text, /data-id=&quot;(\S*?)&quot;/);
    } else if (-1 != text.indexOf("{")) {
        return getMatchedStrs(text, /\{(\S*?)\}/);
    } else {//未知场景
        return text;
    }
}

//获取选项
const getOptions = function (data) {
    let inner = new Array();
    //量表
    if ("star" == data.type) {
        //starBeginNum代表起始点数字，starNum代表个数
        let limit = parseInt(data.starBeginNum) + parseInt(data.starNum);
        for (let i = data.starBeginNum; i < limit; i++) {
            let tmpObj = new Object();
            tmpObj.title = i.toString();
            tmpObj.optionId = i.toString();
            tmpObj.value = -1;
            inner.push(tmpObj);
        }
        return inner;
    }
    //矩阵量表
    if ("matrix_star" == data.type) {
        var subTitlesLength = getJsonLength(data.sub_titles);
        for (let k = 0; k < subTitlesLength; k++) {
            let line = data.sub_titles[k];
            let limit = parseInt(data.starBeginNum) + parseInt(data.starNum);
            for (let i = data.starBeginNum; i < limit; i++) {
                let tmpObj = new Object();
                tmpObj.title = cleanText(line.text) + "_" + i;
                tmpObj.optionId = line.id + "_" + i + "_" + i;
                tmpObj.value = -1;
                inner.push(tmpObj);
            }
        }
        return inner;
    }
    //多项填空
    if ("blanks" == data.type) {
        let bsLength = getJsonLength(data.blank_setting);
        for (let i = 0; i < bsLength; i++) {
            let tmpObj = new Object();
            tmpObj.title = i.toString();
            if (data.blank_setting[i].required) {
                tmpObj.title = i + "_必填";
            }
            tmpObj.optionId = data.blank_setting[i].id;
            tmpObj.value = -1;
            inner.push(tmpObj);
        }
        return inner;
    }
    //矩阵填空
    if ("matrix_blank" == data.type) {
        return buildMatrixBlank(data);
    }

    var optionsLength = getJsonLength(data.options);
    for (var i = 0; i < optionsLength; i++) {
        let tmpObj = new Object();

        let choiceTitle = cleanText(data.options[i].text);
        switch (data.type) {
            case "radio"://单选
            case "checkbox"://多选
            case "select"://下拉选
            case "sort"://排序
                tmpObj.title = choiceTitle;
                tmpObj.optionId = data.options[i].id;
                if (-1 != choiceTitle.indexOf("____") && -1 != data.options[i].text.indexOf("fillblank")) {
                    tmpObj.title = choiceTitle.replace("____", "") + "|underline";
                    if (0 < getJsonLength(data.blank_setting)) {
                        let bs = data.blank_setting[0];
                        if (!bs.hasOwnProperty("required") || bs.required) { //没有required属性或者有但为true表示必填
                            tmpObj.title += "必填";
                        }
                    }
                    tmpObj.optionId += "|" + getBlankId(data.options[i].text);
                }
                tmpObj.value = -1;
                break;
            case "matrix_radio"://矩阵单选
            case "matrix_checkbox"://矩阵多选
                return buildMatrixChoise(data);
            default:
                break;
        }
        inner.push(tmpObj);
    }
    return inner;
}

//获取匹配到的字符串
const getExecStrs = function (str) {
    var reg = /q\.(.+)\.selected/g;
    var list = []
    var result = null
    do {
        result = reg.exec(str)
        result && list.push(result[1])
    }
    while (result)
    return list
}

//获取questionId
const getQuestId = function (str) {
    var reg = /q\.(.+)\.answered/g;
    var list = []
    var result = null
    do {
        result = reg.exec(str)
        result && list.push(result[1])
    }
    while (result)
    return list
}

//通过指定questId获取旗下optionId数组
const getOptionIdArr = function (dataArray, questId) {
    let optionIdArr = new Array();
    for (let i = 0; i < dataArray.length; i++) {
        if (questId == dataArray[i].qid) {
            for (let k = 0; k < dataArray[i].inner.length; k++) {
                optionIdArr.push(dataArray[i].inner[k].optionId);
            }
        }
    }
    return optionIdArr;
}

//更新跳转逻辑题号
const updateSkipLogic = function (surveyRules, dataArray) {
    // let jumpData = new Array();
    if (!surveyRules.hasOwnProperty('list')) {
        return;
    }
    let ruleLength = getJsonLength(surveyRules.list);
    if (0 == ruleLength) {
        return;
    }
    let jumpDict = []; // {questionId:[obj1,obj2]}
    for (let i = 0; i < ruleLength; i++) {
        let ruleStr = JSON.stringify(surveyRules.list[i].rule);
        //例1 '{"==":[{"var":"q.q-1-CfjY.options.o-3-zUtI.selected"},true]}'
        //例2 '{"==":[{"var":"q.q-14-BqU2.answered"},true]}'
        let dstId = surveyRules.list[i].action[0].q_target_id;
        if (-1 != ruleStr.indexOf("answered")) {//答题则跳转，即选择没有下面options选定的选项
            let srcId = getQuestId(ruleStr);
            let optionIdArr = getOptionIdArr(dataArray, srcId);
            for (let k = 0; k < optionIdArr.length; k++) {
                let jmpObj = new Object();
                jmpObj.destId = dstId; // 跳转的id。跳到结束赋值-1或0
                jmpObj.optionId = optionIdArr[k];
                if (undefined == jumpDict[srcId]) {//不存在
                    let jumpData = new Array();
                    jumpData.push(jmpObj);
                    jumpDict[srcId] = jumpData;
                } else {//已存在
                    //如果存在某题对应的optionId则不添加
                    let existJmpDataArr = jumpDict[srcId];
                    let addFlag = true;
                    for (let m = 0; m < existJmpDataArr.length; m++) {
                        if (existJmpDataArr[m].optionId == jmpObj.optionId) {
                            addFlag = false;
                            break;
                        }
                    };
                    if (addFlag) {
                        jumpDict[srcId].push(jmpObj);
                    }
                }
            }
        } else if (-1 != ruleStr.indexOf("options")) {//选择某个选项跳转
            let tmpStr = getExecStrs(ruleStr);//例 'q-1-CfjY.options.o-3-zUtI'
            let ret = tmpStr[0].replace('options.', '');//例 'q-1-CfjY.o-3-zUtI'
            let idx = ret.indexOf('.');//例 分界点下标

            let jmpObj = new Object();
            jmpObj.destId = dstId; // 跳转的id。跳到结束赋值-1或0
            jmpObj.optionId = ret.substring(idx + 1, ret.length);   // 选中选项id，选中才跳转。例 'o-3-zUtI'
            let srcId = ret.substring(0, idx); //例 'q-1-CfjY'
            if (undefined == jumpDict[srcId]) {//不存在
                let jumpData = new Array();
                jumpData.push(jmpObj);
                jumpDict[srcId] = jumpData;
            } else {//已存在
                //如果存在某题对应的optionId则用当前覆盖（先删除原来的后添加现在的）
                let existJmpDataArr = jumpDict[srcId];
                //过滤掉同optionId的项
                existJmpDataArr = existJmpDataArr.filter(item => {
                    if (item.optionId != jmpObj.optionId) {
                        return item;
                    }
                });
                jumpDict[srcId] = existJmpDataArr;
                jumpDict[srcId].push(jmpObj);
            }
        }
    }

    let dataLength = getJsonLength(dataArray);

    for (let i = 0; i < dataLength; i++) {
        if (undefined != jumpDict[dataArray[i].qid]) {
            dataArray[i].hasJump = true;
            dataArray[i].jumpData = jumpDict[dataArray[i].qid];
        }
    }
}


//更新显示逻辑字典（注：只有逻辑或关系）
const updateLogicDict4display = function (logicDict4display, options, id) {
    let optionsLength = getJsonLength(options);
    let currentTopicFlagDict = [];
    for (let i = 0; i < optionsLength; i++) {
        if (options[i].hasOwnProperty("display") && getJsonLength(options[i].display) > 0) {
            tmpDic = options[i].display;
            for (let key in tmpDic) {//key为dstId即目标题ID
                if (undefined == logicDict4display[key]) { //不存在
                    logicDict4display[key] = id + "," + (i + 1);
                    currentTopicFlagDict[key] = true;
                } else { //存在
                    let tmpVal = logicDict4display[key];
                    if (true == currentTopicFlagDict[key]) { // key对应的当前题目
                        logicDict4display[key] = tmpVal + ";" + (i + 1);
                    } else {// 非当前题目，即新题号
                        logicDict4display[key] = tmpVal + "$" + id + "," + (i + 1);//根据框架依照问卷星规则：逻辑与用|，逻辑或用$
                        currentTopicFlagDict[key] = true;
                    }
                }
            }
        }
    }
}

//更新显示逻辑题号
const updateDisplayLogic = function (logicDict4display, dataArray) {
    let jsonLen = getJsonLength(dataArray);
    for (let i = 0; i < jsonLen; i++) {
        if (undefined != logicDict4display[dataArray[i].qid]) {
            dataArray[i].relation = logicDict4display[dataArray[i].qid];
        }
    }
}

//获取返回range
const getRange = function (qst) {
    if ("checkbox" == qst.type) {//多选
        //多选要设置最大值，如果没有预设max则取选项数量
        let range = {
            minvalue: qst.hasOwnProperty('min_length') ? parseInt(qst.min_length) : 1,
            maxvalue: qst.hasOwnProperty('max_length') ? parseInt(qst.max_length) : getJsonLength(qst.options)
        };
        return range;
    } else if ("star" == qst.type) {//量表
        let range = {
            minvalue: parseInt(qst.star_begin_num),
            maxvalue: parseInt(qst.star_num)
        };
        return range;
    }
    return null;
}

//获取是否必须条件
const getRequired = function (qst) {
    if (qst.hasOwnProperty("required")) {
        return qst.required;
    } else {
        return false;
    }
}

//获取跳题存在与否
const getJumpExistent = function (version) {
    if ("1.0" == version) {//跳转逻辑生效
        return true;
    } else {//if("2.0" == version) {//显示逻辑生效
        return false;
    }
}

//DSL逻辑构建
const buildDSLLogic = function () {//deprecated
    let tmp = new Object();
    tmp.id = 0;
    tmp.qid = '';
    tmp.range = null;
    tmp.relation = '';
    tmp.inner = null;
    tmp.isRequired = true;
    tmp.title = '';
    tmp.hasJump = false;
    tmp.jumpData = null;

    tmp.type = "暂不支持DSL逻辑";
    return tmp;
}

// 获取DSL题目数组
const getDslQstArr = function (survey_dsl) {
    let dslArr = new Array();
    let tmpCode = survey_dsl.code;
    if (null == tmpCode || "" == tmpCode) {
        return dslArr;
    }
    let dslData = tmpCode.replaceAll("&#96;", "`");//转换原始dsl语句
    // let dslData = "if `q-8-61e1` == 0 then hide `q-9-dedb`, `q-10-0f80`, `q-11-a0e3`, `q-12-98b2`, `q-13-530a`\nif `q-28-dXgi::o-1-Tgsm` then hide `q-15-5e69`, `q-16-3f6d`, `q-28-bBXA`, `q-18-a1e6`, `q-19-9d66`, `q-20-d19d`, `q-21-c87d`, `q-24-a02e`, `q-25-8292`, `q-26-9eaa`, `q-27-03ec`\nif `q-21-c87d::o-102-4bdf` and `q-15-5e69` > 0 then hide `q-24-a02e`, `q-22-4d44`, `q-23-79d3`";
    let reg = /if (`.*`)+.* then/ig;
    let ifArrResult = dslData.match(reg);
    // console.log(ifArrResult);
    for (var i = 0; i < ifArrResult.length; i++) {
        let newReg = /`(.*?)`/ig;
        let qstArr = ifArrResult[i].match(newReg);
        // console.log(qstArr);

        for (var j = 0; j < qstArr.length; j++) {
            let qst = qstArr[j].split("::")[0];
            dslArr.push(qst.replaceAll("`", ""));
        }
    }
    return dslArr;
}

//更新DSL题
const updateDslQst = function (dslQstArr, dataArray) {
    for (let i = 0; i < dataArray.length; i++) {
        if (-1 != dslQstArr.indexOf(dataArray[i].qid)) {
            dataArray[i].type = "DSL逻辑题";
        }
    }
}

// 获取系统类型
const traslateType = function (type, srcType) {
    if ("单选" == type) {
        return "SINGLE";
    } else if ("多选" == type) {
        return "MULTIPLE";
    } else if ("下拉选项" == type) {
        return "SINGLE_SELECT";
    } else if ("排序选择" == type) {
        return "SORTED";
    } else if ("量表" == type) {
        return "SCALE";
    } else if ("矩阵单选" == type | "矩阵量表" == type) {
        return "MATRIX";
    } else if ("矩阵多选" == type) {
        return "MULTIPLE_MATRIX";
    } else if ("滑动条" == type) {
        return "SINGLE_SLIDE";
    } else if ("矩阵滑动" == type) {
        return "SLIDE";
    } else if ("比重" == type) {
        return "RATE";
    } else if ("文本框" == type) {
        return "TEXT";
    } else if ("填空" == type) {
        if ("datetime" == srcType) {//日期题
            return "DATE";
            // } else if() {//地区题
            //     return "AREA";
        } else if("blanks" == srcType) {
            return "MULTIPLE_TEXT";
        } else if ("chained_selects" == srcType) {//级联题
            return "CASCADE_DROPDOWN";
        } else {
            return "TEXT";
        }
        
    } else if ("级联选择" == type) {
        return "CASCADE_DROPDOWN";
    } else if ("矩阵填空" == type) {
        return "MATRIX_TEXT";
    } else if ("占位题" == type) {
        return "DESCRIPTION";
    } else {
        return type;
    }
}

// 转译是否必须：0代表非必填；1代表必填
const traslateRequired = function (isReq) {
    if (isReq) { //必填
        return '1';
    }
    return '0';
}

// 判断是否为填空类题型
const isText = function (curQst) {
    if ("TEXT" == curQst.sys_type || "DATE" == curQst.sys_type || "MULTIPLE_TEXT" == curQst.sys_type || "MATRIX_TEXT" == curQst.sys_type) {
        return true;
    }
    return false;
}

// 设置最大最小值，如果存在的话
const setMaxAndMin4ScaleOrMatrix = function (curQst, srcOptions) {
    if (null != curQst.range) {
        return;
    }
    let range = null;
    if ("SCALE" == curQst.type) {
        range = {
            minvalue: 1,
            maxvalue: getJsonLength(curQst.option)
        };
    } else if ("MATRIX" == curQst.type) {
        range = {
            minvalue: -1,//这里只做长度用，最小值用-1来标识
            maxvalue: getJsonLength(srcOptions)
        };
    }
    curQst.range = range;
}

// 设置最大最小值，如果存在的话
const setMaxAndMinIfExist = function (curQst, range) {
    if("SCALE" == curQst.sys_type) { //量表不设置max和min
        return;
    }
    if (undefined == range || null == range) {
        return;
    }
    curQst.min_oper_num = range.minvalue;
    curQst.max_oper_num = range.maxvalue;
}

// 设置选项维度跳题逻辑，如果存在的话
const setJumpOnOptIfExist = function(curQst, option, jumpDict) {
    let optVal = jumpDict[option.value];
    if(curQst.is_jump && undefined != optVal) {
        option.is_jump = true; // 是否跳题
        option.jump_to = optVal; // 跳到第几题
    }
}

// 获取option的is_text字段值
const getOptionIsText = function (curQst, optName) {
    if ("SINGLE" == curQst.sys_type || "MULTIPLE" == curQst.sys_type) {
        if(optName.endsWith('|underline')) {
            return 1;//return true; //问卷星里竟然是数字1，无填空是返回false
        }
    }
    return curQst.is_text; 
}

// 转译选项
const tanslateOptions = function (curData, curQst, dataIndexDict, jumpDict) {
    let optionList = curData.inner;
    let optArr = new Array();
    let len = getJsonLength(optionList);
    if("SCALE" == curQst.sys_type) { // 量表
        len = curData.range.maxvalue;
    }
    //{"lastDataIndex" : 0, "curQstDataIndex":[]};
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    for (let i = 0; i < len; i++) {
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样

        if ("SCALE" == curQst.sys_type) {// 量表
            if(1 == i+1) {
                option.name = curData.srcQstData.star_show_custom_start; // 题目的选项名称
            } else if(len == i+1) {
                option.name = curData.srcQstData.star_show_custom_end; // 题目的选项名称
            } else {
                option.name = "";
            }
            option.value = (i+1).toString(); // 题目的选项值
            option.real_value = i+1; // 问卷提交对应的值
            option.text = '';
            // if(curData.srcQstData.hasOwnProperty('star_attach_tags') && getJsonLength(curData.srcQstData.star_attach_tags) > 0) {//评价题
            //     option.name = '';
            //     option.text = '';
            // }
        } else {
            option.name = optionList[i].title; // 题目的选项名称
            option.value = (i+1).toString(); // 题目的选项值
            option.real_value = optionList[i].optionId; // 问卷提交对应的值
            option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        }
        option.title = curQst.title + option.name; // 改成和问卷星解析一样：题目标题+选项名称
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        setJumpOnOptIfExist(curQst, option, jumpDict); //设置选项维度跳题逻辑，如果存在的话

        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = getOptionIsText(curQst, option.name); // 是否需要填空
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = curQst.min_oper_num; // 最小值
        option.max_oper_num = curQst.max_oper_num; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵or多填
        if ("MULTIPLE" == curQst.sys_type || "SORTED" == curQst.sys_type) {//多选每个选项都要有索引
            option.data_index = lastDataIndex + i; // 数据库索引
            dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
        } else {
            option.data_index = lastDataIndex; // 数据库索引
        }
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
    }
    if ("MULTIPLE" == curQst.sys_type || "SORTED" == curQst.sys_type) {
        dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    } else if("DESCRIPTION" == curQst.sys_type) {
        //描述类占位题不生成dataIndexDict值
    } else {
        dataIndexDict["curQstDataIndex"].push(lastDataIndex);
        dataIndexDict["lastDataIndex"] = lastDataIndex + 1;
    }
    return optArr;
}

// 获取子节点选项（只针对矩阵or多填）
const getChildOption = function (maxNum, curQst, oldData) {
    let optArr = new Array();
    if ("MULTIPLE_TEXT" == curQst.sys_type) { // 多项填空
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title = curQst.title; // 父题目
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = curQst.name; // 题目的选项名称
        option.value = (curQst.value).toString(); // 题目的选项值
        option.real_value = curQst.real_value; // 问卷提交对应的值
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = curQst.is_text; // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = curQst.min_oper_num; // 最小值
        option.max_oper_num = curQst.max_oper_num; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵题or多填
        option.data_index = curQst.data_index; // 数据库索引
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
        return optArr;
    }
    if (undefined == maxNum || null == maxNum) {
        return optArr;
    }
    for (let i = 0; i < maxNum; i++) {//矩阵单选，矩阵量表，矩阵多选，矩阵填空
        let optName = "";
        let optId = "";
        if("MATRIX_TEXT" == curQst.sys_type) {//矩阵填空
            optName = oldData.srcQstData.blanks[i].text;
            optId = oldData.srcQstData.blanks[i].blank_setting.id;
        } else {
            optName = oldData.srcQstData.options[i].text;
            optId = oldData.srcQstData.options[i].id;
        }

        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title = curQst.title + optName; // 父题目+本title
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = optName; // 题目的选项名称
        option.value = (i+1).toString(); // 题目的选项值
        option.real_value = optId; // 问卷提交对应的值
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = curQst.is_text; // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = 0; // 最小值
        option.max_oper_num = 0; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵题or多填
        option.data_index = curQst.data_index; // 数据库索引
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
    }
    return optArr;
}

// 获取多项填空标题ID字典
const getMultiTextDict = function(content) {
    //例content="姓名： ____{fillblank-db2a}年龄： ____{fillblank-820e}电话： ____{fillblank-752e}"
    let cttArr = content.split("}");
    let multiTextDict = {};
    for(let i=0; i<cttArr.length-1; i++) {
        let tmpArr = cttArr[i].split("____{");
        multiTextDict[tmpArr[1]] = tmpArr[0];
    }
    return multiTextDict;
}

// 获取矩阵多选子节点选项
const getChildOptionOnly4MultiMatrix = function(len, curQst, oldData, dataIndexDict) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let optArr = new Array();
    for (let i = 0; i < len; i++) {
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title = curQst.title + oldData.srcQstData.options[i].text; // 父题目+本title
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = oldData.srcQstData.options[i].text; // 题目的选项名称
        option.value = (i+1).toString();
        option.real_value = oldData.srcQstData.options[i].id; // 问卷提交对应的值
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = curQst.is_text; // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = 0; // 最小值
        option.max_oper_num = 0; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵题or多填
        option.data_index = lastDataIndex + i; // 数据库索引
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
        dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
    }
    dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    return optArr;
}

// 获取矩阵填空的子节点选项
const getChildOption4MatrixText = function (len, curQst, oldData, dataIndexDict) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let optArr = new Array();
    for (let i = 0; i < len; i++) {
        let option = new Object();
        option.tid = curQst.tid; //题目计数序号-和题目外部一样
        option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
        option.title = curQst.title + oldData.srcQstData.blanks[i].text; // 父题目+本title
        option.title_type = curQst.title_type; // 和题目外部一样
        option.sys_type = curQst.sys_type; // 和题目外部一样
        option.name = oldData.srcQstData.blanks[i].text; // 题目的选项名称
        option.value = (i+1).toString();
        option.real_value = oldData.srcQstData.blanks[i].blank_setting.id; // 问卷提交对应的值
        option.is_jump = false; // 是否跳题
        option.jump_to = ""; // 跳到第几题
        option.req = curQst.req; // 是否必须 - 和题目外部一样
        option.is_text = curQst.is_text; // 是否需要填空 - 默认false
        option.relation = ""; // 关联 - 内部不需要这个字段
        option.min_oper_num = 0; // 最小值
        option.max_oper_num = 0; // 最大值
        option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
        option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
        option.is_reverse = false; // 是否反向 - 默认false
        option.options = []; // 选项
        option.children = []; // 针对矩阵题or多填
        option.data_index = lastDataIndex + i; // 数据库索引
        option.is_repeat = false; // 是否去重 - 解析默认false
        optArr.push(option);
        dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
    }
    dataIndexDict["lastDataIndex"] = lastDataIndex + len;
    return optArr;
}

// 获取子选项（只针对矩阵or多填）
const getChildren = function (oldData, curQst, dataIndexDict) {
    let optionList = oldData.inner;
    let range = oldData.range;
    let childArr = new Array();

    //{"lastDataIndex" : 0, "curQstDataIndex":[]};
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let len = 0;
    // if("matrix_radio" == oldData.srcQstData.type || "matrix_checkbox" == oldData.srcQstData.type || "matrix_star" == oldData.srcQstData.type) {
    if ("MATRIX" == curQst.sys_type || "MULTIPLE_MATRIX" == curQst.sys_type || "MATRIX_TEXT" == curQst.sys_type) {//矩阵单选，矩阵量表，矩阵多选，矩阵填空
        subTitles = oldData.srcQstData.sub_titles;
        len = getJsonLength(subTitles);
        for (let i = 0; i < len; i++) {
            let curChild = new Object();
            curChild.tid = curQst.tid; //题目计数序号-和题目外部一样
            curChild.title_id = curQst.title_id; // 题目标题id-和题目外部一样
            curChild.title = curQst.title + subTitles[i].text; //  parent的title + child的name组成一个title
            curChild.title_type = curQst.title_type; // 和题目外部一样
            curChild.sys_type = curQst.sys_type; // 和题目外部一样
            curChild.name = subTitles[i].text; // 题目的选项名称
            curChild.value = (i+1).toString(); 
            curChild.real_value = subTitles[i].id; // 问卷提交对应的值
            curChild.is_jump = false; // 是否跳题
            curChild.jump_to = ""; // 跳到第几题
            curChild.req = curQst.req; // 是否必须 - 和题目外部一样
            curChild.is_text = false; // 是否需要填空 - 默认false
            curChild.relation = ""; // 关联 - 内部不需要这个字段
            curChild.min_oper_num = 0; // 最小值
            curChild.max_oper_num = 0; // 最大值
            setMaxAndMinIfExist(curChild, range);
            curChild.rate = 0; // 权重 - 默认0 - 非问卷解析字段
            curChild.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
            curChild.is_reverse = false; // 是否反向 - 默认false
            curChild.data_index = lastDataIndex + i; // 数据库索引
            if("MULTIPLE_MATRIX" == curQst.sys_type) {//矩阵多选
                curChild.options = getChildOptionOnly4MultiMatrix(getJsonLength(oldData.srcQstData.options), curChild, oldData, dataIndexDict); // 选项
                curChild.data_index = dataIndexDict["lastDataIndex"] - 1; // 数据库索引
                // dataIndexDict["curQstDataIndex"].push(dataIndexDict["lastDataIndex"]);
                // dataIndexDict["lastDataIndex"] = dataIndexDict["lastDataIndex"] + 1;
            } else if ("MATRIX_TEXT" == curQst.sys_type) { // 矩阵填空
                curChild.options = getChildOption4MatrixText(getJsonLength(oldData.srcQstData.blanks), curChild, oldData, dataIndexDict); // 选项
                curChild.data_index = dataIndexDict["lastDataIndex"] - 1; // 数据库索引
            } else {
                curChild.data_index = dataIndexDict["lastDataIndex"] + i; // 数据库索引
                dataIndexDict["curQstDataIndex"].push(dataIndexDict["lastDataIndex"] + i);
                curChild.options = getChildOption(getJsonLength(oldData.srcQstData.options), curChild, oldData); // 选项
            }
            curChild.children = []; // 针对矩阵or多填题
            curChild.is_repeat = false; // 是否去重 - 解析默认false
            childArr.push(curChild);
        }
        if("MULTIPLE_MATRIX" != curQst.sys_type && "MATRIX_TEXT" != curQst.sys_type) {//不是矩阵多选
            dataIndexDict["lastDataIndex"] = dataIndexDict["lastDataIndex"] + len;
        }
    } else if("MULTIPLE_TEXT" == curQst.sys_type) { //多项填空
        len = getJsonLength(oldData.srcQstData.blank_setting);
        for (let i = 0; i < len; i++) {
            let curChild = new Object();
            let itemId = oldData.srcQstData.blank_setting[i].id;
            curChild.tid = curQst.tid; //题目计数序号-和题目外部一样
            curChild.title_id = curQst.title_id; // 题目标题id-和题目外部一样
            curChild.title = curQst.title + getMultiTextDict(oldData.srcQstData.content)[itemId]; //  parent的title + child的name组成一个title
            curChild.title_type = curQst.title_type; // 和题目外部一样
            curChild.sys_type = curQst.sys_type; // 和题目外部一样
            curChild.name = getMultiTextDict(oldData.srcQstData.content)[itemId]; // 题目的选项名称
            curChild.value = (i+1).toString();
            curChild.real_value = itemId; // 问卷提交对应的值
            curChild.is_jump = false; // 是否跳题
            curChild.jump_to = ""; // 跳到第几题
            curChild.req = curQst.req; // 是否必须 - 和题目外部一样
            curChild.is_text = curQst.is_text; // 是否需要填空 - 默认false
            curChild.relation = ""; // 关联 - 内部不需要这个字段
            curChild.min_oper_num = 0; // 最小值
            curChild.max_oper_num = 0; // 最大值
            setMaxAndMinIfExist(curChild, range);
            curChild.rate = 0; // 权重 - 默认0 - 非问卷解析字段
            curChild.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
            curChild.is_reverse = false; // 是否反向 - 默认false
            curChild.data_index = lastDataIndex + i; // 数据库索引
            curChild.options = getChildOption(getJsonLength(oldData.srcQstData.answers), curChild, oldData); // 选项
            curChild.children = []; // 针对矩阵or多填题
            curChild.is_repeat = false; // 是否去重 - 解析默认false
            childArr.push(curChild);
            dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
        }
        dataIndexDict["lastDataIndex"] = dataIndexDict["lastDataIndex"] + len;
    } else {
        len = getJsonLength(optionList);
        for (let i = 0; i < len; i++) {
            let curChild = new Object();
            curChild.tid = curQst.tid; //题目计数序号-和题目外部一样
            curChild.title_id = curQst.title_id; // 题目标题id-和题目外部一样
            curChild.title = curQst.title + optionList[i].title; //  parent的title + child的name组成一个title
            curChild.title_type = curQst.title_type; // 和题目外部一样
            curChild.sys_type = curQst.sys_type; // 和题目外部一样
            curChild.name = optionList[i].title.split("_")[0]; // 题目的选项名称
            curChild.value = (i+1).toString();
            curChild.real_value = optionList[i].optionId; // 问卷提交对应的值
            curChild.is_jump = false; // 是否跳题
            curChild.jump_to = ""; // 跳到第几题
            curChild.req = curQst.req; // 是否必须 - 和题目外部一样
            curChild.is_text = false; // 是否需要填空 - 默认false
            curChild.relation = ""; // 关联 - 内部不需要这个字段
            curChild.min_oper_num = 0; // 最小值
            curChild.max_oper_num = 0; // 最大值
            setMaxAndMinIfExist(curChild, range);
            curChild.rate = 0; // 权重 - 默认0 - 非问卷解析字段
            curChild.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
            curChild.is_reverse = false; // 是否反向 - 默认false
            curChild.data_index = lastDataIndex + i; // 数据库索引
            curChild.options = getChildOption((range == undefined || range == null) ? null : range.maxvalue, curChild, oldData); // 选项
            curChild.children = []; // 针对矩阵or多填题
            curChild.is_repeat = false; // 是否去重 - 解析默认false
            childArr.push(curChild);
            dataIndexDict["curQstDataIndex"].push(lastDataIndex + i);
        }
        dataIndexDict["lastDataIndex"] = dataIndexDict["lastDataIndex"] + len;
    }
    return childArr;
}

// 构建填空option
const buildTextOption = function (curQst, dataIndexDict) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let option = new Object();
    option.tid = curQst.tid; //题目计数序号-和题目外部一样
    option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
    option.title = curQst.title; // 和题目外部一样
    option.title_type = curQst.title_type; // 和题目外部一样
    option.sys_type = curQst.sys_type; // 和题目外部一样
    option.name = ""; // 题目的选项名称
    option.value = "1";
    option.real_value = ""; // 问卷提交对应的值
    option.is_jump = false; // 是否跳题
    option.jump_to = ""; // 跳到第几题
    option.req = curQst.req; // 是否必须 - 和题目外部一样
    option.is_text = curQst.is_text; // 是否需要填空 - 默认false
    option.relation = ""; // 关联 - 内部不需要这个字段
    option.min_oper_num = curQst.min_oper_num; // 最小值
    option.max_oper_num = curQst.max_oper_num; // 最大值
    option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
    option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
    option.is_reverse = false; // 是否反向 - 默认false
    option.options = []; // 选项
    option.children = []; // 针对矩阵or多填
    option.data_index = lastDataIndex; // 数据库索引
    option.is_repeat = false; // 是否去重 - 解析默认false
    dataIndexDict["curQstDataIndex"].push(lastDataIndex);
    dataIndexDict["lastDataIndex"] = lastDataIndex + 1;
    return option;
}

// 构建级联下拉option
const buildCascadeOption = function (curQst, dataIndexDict, srcData) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let option = new Object();
    option.tid = curQst.tid; //题目计数序号-和题目外部一样
    option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
    option.title = curQst.title; // 和题目外部一样
    option.title_type = curQst.title_type; // 和题目外部一样
    option.sys_type = curQst.sys_type; // 和题目外部一样
    option.name = srcData.levels; // 题目的选项名称，这里用于存放级联层级标题，比如["一级标题","二级标题","三级标题"],
    option.value = "1";
    option.real_value = ""; // 问卷提交对应的值
    option.is_jump = false; // 是否跳题
    option.jump_to = ""; // 跳到第几题
    option.req = curQst.req; // 是否必须 - 和题目外部一样
    option.is_text = curQst.is_text; // 是否需要填空 - 默认false
    option.relation = ""; // 关联 - 内部不需要这个字段
    option.min_oper_num = curQst.min_oper_num; // 最小值
    option.max_oper_num = curQst.max_oper_num; // 最大值
    option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
    option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
    option.is_reverse = false; // 是否反向 - 默认false
    option.options = srcData.groups; // 选项，这里用于存放级联数据集
    option.children = []; // 针对矩阵or多填
    option.data_index = lastDataIndex; // 数据库索引
    option.is_repeat = false; // 是否去重 - 解析默认false
    dataIndexDict["curQstDataIndex"].push(lastDataIndex);
    dataIndexDict["lastDataIndex"] = lastDataIndex + 1;
    return option;
}

// 获取data_index数据中的多选选项
const getDataIdxCheckboxOption = function (curQst, dataIndexDict,idx) {
    let lastDataIndex = dataIndexDict["lastDataIndex"];
    let option = new Object();
    option.tid = curQst.tid; //题目计数序号-和题目外部一样
    option.title_id = curQst.title_id; // 题目标题id-和题目外部一样
    option.title = curQst.title; // 和题目外部一样
    option.title_type = curQst.title_type; // 和题目外部一样
    option.sys_type = curQst.sys_type; // 和题目外部一样
    option.name = curQst.name; // 题目的选项名称
    option.value = idx+1;
    option.real_value = curQst.value; // 问卷提交对应的值
    option.is_jump = false; // 是否跳题
    option.jump_to = ""; // 跳到第几题
    option.req = curQst.req; // 是否必须 - 和题目外部一样
    option.is_text = curQst.is_text; // 是否需要填空 - 默认false
    option.relation = ""; // 关联 - 内部不需要这个字段
    option.min_oper_num = curQst.min_oper_num; // 最小值
    option.max_oper_num = curQst.max_oper_num; // 最大值
    option.rate = 0; // 权重 - 默认0 - 非问卷解析字段
    option.text = ""; // 填空内容 - 默认空字符串 - 非问卷解析字段
    option.is_reverse = false; // 是否反向 - 默认false
    option.options = []; // 选项
    option.children = []; // 针对矩阵or多填
    option.data_index = lastDataIndex; // 数据库索引
    option.is_repeat = false; // 是否去重 - 解析默认false
    dataIndexDict["curQstDataIndex"].push(lastDataIndex);
    dataIndexDict["lastDataIndex"] = lastDataIndex + 1;
    return option;
}

// 获取data_index数据
const getDataIndexArr = function (result) {
    let dataIndexArr = new Array(); // 数据库对应的数据

    let counter = 0;
    let dataArr = result.data; // new Array();//
    let len = getJsonLength(dataArr);
    let dataIndexDict = { "lastDataIndex": 0, "curQstDataIndex": [] };//用于记录上一个索引，和当前题目data_index集合
    for (let i = 0; i < len; i++) {
        let jumpDict = {};
        //console.log(key);
        // if ("多选" == dataArr[i].type) {
        //     let optionList = dataArr[i].inner;
        //     let len = getJsonLength(optionList);
        //     for (let j = 0; j < len; j++) {
        //         let curData = dataArr[i];
        //         let tmp = new Object();
        //         tmp.tid = curData.id; // 题目的计数序号，唯一但不用于提交，可在relation中使用
        //         tmp.title_id = curData.qid; // 题目id_每个问卷每个题目唯一标识，提交用
        //         tmp.title = tmp.title_id + curData.title; // 题目的标题，title_id + 标题字符串
        //         tmp.title_type = curData.srcType; // 题目类型_每个平台自己的题目类型_1_23
        //         tmp.sys_type = traslateType(curData.type, curData.srcType); // 内部平台题目类型
        //         tmp.name = curData.title; // 题目名称，给制单人看的
        //         tmp.value = ""; // 值 - 题目维度下不需要填
        //         tmp.is_jump = curData.hasJump; // 是否是跳题 "1" || True | ""
        //         tmp.jump_to = "";//null == curData.jumpData ? "" : curData.jumpData; // 跳到哪个题目 "" / title_id
        //         tmp.req = traslateRequired(curData.isRequired); // 是否必须题 "1" / "0" || ""
        //         tmp.is_text = isText(tmp); // 是否填空题 bool
        //         tmp.relation = curData.relation;
        //         tmp.min_oper_num = 0; // 最小值
        //         tmp.max_oper_num = 0; // 最大值
        //         setMaxAndMinIfExist(tmp, curData.range);
        //         tmp.rate = 0; // 权重 - 题目维度下不需要填
        //         tmp.text = ""; // 填空内容 - 题目维度下不需要填
        //         tmp.is_reverse = false; //是否反转 - 题目维度下不需要填
        //         tmp.options = [getDataIdxCheckboxOption(tmp, dataIndexDict,j)];
        //         tmp.children = [];
        //         tmp.data_index = dataIndexDict["curQstDataIndex"]; // 数据库索引
        //         dataIndexDict["curQstDataIndex"] = [];

        //         dataIndexArr.push(tmp);
        //     }
        // } else {
        let curData = dataArr[i];
        let tmp = new Object();
        tmp.tid = curData.id; // 题目的计数序号，唯一但不用于提交，可在relation中使用
        tmp.page_id = curData.pageId; // 页码ID，提交问卷用
        tmp.title_id = curData.qid; // 题目id_每个问卷每个题目唯一标识，提交用
        tmp.title = tmp.title_id + curData.title; // 题目的标题，title_id + 标题字符串
        tmp.title_type = curData.srcType; // 题目类型_每个平台自己的题目类型_1_23
        tmp.sys_type = traslateType(curData.type, curData.srcType); // 内部平台题目类型
        tmp.name = curData.title; // 题目名称，给制单人看的
        tmp.value = ""; // 值 - 题目维度下不需要填
        tmp.is_jump = curData.hasJump; // 是否是跳题 "1" || True | ""
        if(curData.hasJump) {
            jumpDict = translate2JumpDict(curData.jumpData);
        }
        tmp.jump_to = "";//null == curData.jumpData ? "" : curData.jumpData; // 跳到哪个题目 "" / title_id
        tmp.req = traslateRequired(curData.isRequired); // 是否必须题 "1" / "0" || ""
        tmp.is_text = isText(tmp); // 是否填空题 bool
        tmp.relation = curData.relation;
        tmp.min_oper_num = 0; // 最小值
        tmp.max_oper_num = 0; // 最大值
        setMaxAndMinIfExist(tmp, curData.range);
        tmp.rate = 0; // 权重 - 题目维度下不需要填
        tmp.text = ""; // 填空内容 - 题目维度下不需要填
        tmp.is_reverse = false; //是否反转 - 题目维度下不需要填
        tmp.options = [];
        tmp.children = [];
        if ("MATRIX" == tmp.sys_type || "MULTIPLE_MATRIX" == tmp.sys_type || "MATRIX_TEXT" == tmp.sys_type
            || "MULTIPLE_TEXT" == tmp.sys_type) { // 矩阵or多填题
            tmp.children = getChildren(curData, tmp, dataIndexDict);
        } else if ("TEXT" == tmp.sys_type || "AREA" == tmp.sys_type || "DATE" == tmp.sys_type) { // 填空类题型
            tmp.options.push(buildTextOption(tmp, dataIndexDict));
        } else if ("CASCADE_DROPDOWN" == tmp.sys_type) { // 级联下拉题
            tmp.options.push(buildCascadeOption(tmp, dataIndexDict, curData.srcQstData));
        } else {
            tmp.options = tanslateOptions(curData, tmp, dataIndexDict, jumpDict); // 选项
        }
        tmp.data_index = dataIndexDict["curQstDataIndex"]; // 数据库索引
        tmp.is_repeat = false; // 是否去重 - 题目维度下不需要填 - 对于解析来说，默认false
        dataIndexDict["curQstDataIndex"] = [];

        dataIndexArr.push(tmp);
        // }
    }
    let newDataIndexArr = convertDataIndexArr(dataIndexArr); // 转换data_index数组为wjx格式
    return newDataIndexArr;//dataIndexArr;
}

// 转换data_index数组为wjx格式
const convertDataIndexArr = function (dataIndexArr) {
    let newDataIndexArr = new Array();
    let len = getJsonLength(dataIndexArr);
    counter = 0;
    for (let i = 0; i < len; i++) {
        let curData = dataIndexArr[i];
        if ("MULTIPLE_MATRIX" == curData.sys_type ) {// 矩阵多选：拆children中的options，但option值取原来整体options
            for (let j = 0; j < curData.children.length; j++) {//遍历children
                let child = curData.children[j];
                let options = child.options;
                let optStr = JSON.stringify(options);
                for (let k = 0; k < options.length; k++) {
                    let newTmp = options[k];
                    newTmp.index = counter++;
                    newTmp.options = JSON.parse(optStr);
                    newDataIndexArr.push(newTmp);
                }
            }
        } else if ("MATRIX_TEXT" == curData.sys_type) {// 矩阵填空：拆children中的options
            curData.children.forEach(child => {
                child.options.forEach(option => {                        
                    let newTmp = option;
                    newTmp.index = counter++;
                    newTmp.options = [JSON.parse(JSON.stringify(option))];
                    newDataIndexArr.push(newTmp);
                });                    
            });
        } else if ("SINGLE_SLIDE" == curData.sys_type) {// 单选滑动条：拆options，但title和name取原来整体title和name
            curData.children.forEach(child => {
                let newTmp = child;
                newTmp.title = curData.title;
                newTmp.name = curData.name;
                newTmp.index = counter++;
                newDataIndexArr.push(newTmp);
            });
        } else if ("MATRIX" == curData.sys_type || "MULTIPLE_TEXT" == curData.sys_type || "SLIDE" == curData.sys_type ) { // 矩阵or多填题：拆children
            curData.children.forEach(child => {
                let newTmp = child;
                newTmp.index = counter++;
                newDataIndexArr.push(newTmp);
            });
        } else if ("MULTIPLE" == curData.sys_type || "SORTED" == curData.sys_type || "RATE" == curData.sys_type ) { // 多选，排序和比重题：拆options
            curData.options.forEach(option => {
                let newTmp = option;
                newTmp.index = counter++;
                newTmp.options = [JSON.parse(JSON.stringify(option))];
                newDataIndexArr.push(newTmp);
            });
        } else {
            let newTmp = curData;
            newTmp.index = counter++;
            newDataIndexArr.push(newTmp);
        }
    }
    return newDataIndexArr;
}

// 转换为jump字典
const translate2JumpDict = function (oldJumpData) {
    let jumpDict = {};
    let len  = getJsonLength(oldJumpData);
    for(let i=0; i<len; i++) {
        jumpDict[oldJumpData[i].optionId] = oldJumpData[i].destId;
    }
    return jumpDict;
}

// 将指定json数据中的real_value替换成rl_value
const modifyRealValueToRlValue = function (jsonData) {
    let len = getJsonLength(jsonData);
    const traverse = function (obj) {
        if (typeof obj !== 'object' || obj === null) {
            return;
        }
        for (let key in obj) {
            if (obj.hasOwnProperty('real_value')) {
                obj['rl_value'] = obj['real_value'];
                delete obj['real_value'];
            } else {
                traverse(obj[key]);
            }
        }
    };
    traverse(jsonData);
    return jsonData;
}

// 获取选项option的值列表
const getOptionsValueList = function (options) {
    let valueList = new Array();
    for (let i = 0; i < options.length; i++) {
        valueList.push(options[i].value);
    }
    return valueList;
}

// 获取选项option的范围值列表
const getOptionsRangeValueList = function (curData) {
    let valueList = new Array();
    let minVal = curData.min_oper_num;
    let maxVal = curData.max_oper_num;
    for (let i = minVal; i <= maxVal; i++) {
        valueList.push(i);
    }
    return valueList;
}

// 增加valid_values字段
const addValidValues = function (dataIndexArr) {
    let len = getJsonLength(dataIndexArr);
    let sortedQstList = new Array();// 排序题列表，由于其值分散需要收集到一起
    let sortedQstValueList = [-3, -2]; // 排序题值列表
    // 根据每道题的类型添加valid_values字段
    for (let i = 0; i < len; i++) {
        let curData = dataIndexArr[i];
        if ("SINGLE" == curData.sys_type) {// 单选题
            curData.valid_values = [-3].concat(getOptionsValueList(curData.options));
        } else if ("MULTIPLE" == curData.sys_type) {// 多选题
            curData.valid_values = [-3, -2, 0, 1];
        } else if ("SINGLE_SELECT" == curData.sys_type) {// 下拉选择
            curData.valid_values = [-3, -2].concat(getOptionsValueList(curData.options));
        } else if ("SORTED" == curData.sys_type) {// 排序题
            sortedQstList.push(curData);
            sortedQstValueList = sortedQstValueList.concat(getOptionsValueList(curData.options));
        } else if ("SCALE" == curData.sys_type) {// 量表题
            curData.valid_values = [-3].concat(getOptionsValueList(curData.options));
        } else if ("MATRIX" == curData.sys_type) {// 矩阵单选
            curData.valid_values = [-3].concat(getOptionsValueList(curData.options));
        } else if ("MULTIPLE_MATRIX" == curData.sys_type) {// 矩阵多选
            curData.valid_values = [-3, -2, 0, 1];
        } else if ("SINGLE_SLIDE" == curData.sys_type) {// 单项滑动题
            curData.valid_values = getOptionsRangeValueList(curData).concat([-3]);
        } else if ("SLIDE" == curData.sys_type) {// 矩阵滑动题
            curData.valid_values = getOptionsRangeValueList(curData).concat([-3]);
        } else if ("RATE" == curData.sys_type) {// 比重题
            curData.valid_values = getOptionsRangeValueList(curData).concat([-3]);
        } else if ("DATE" == curData.sys_type) {// 日期题
            curData.valid_values = null;
        } else if ("AREA" == curData.sys_type) {// 地区题
            curData.valid_values = null;
        } else if ("TEXT" == curData.sys_type) {// 填空题
            curData.valid_values = null;
        } else if ("MULTIPLE_TEXT" == curData.sys_type) {// 多项填空
            curData.valid_values = null;
        } else if ("MATRIX_TEXT" == curData.sys_type) {// 矩阵填空
            curData.valid_values = null;
        } else {// DESCRIPTION描述类占位题
            curData.valid_values = null;
        }
    }
    // 处理排序题的valid_values字段
    for (let i = 0; i < sortedQstList.length; i++) {
        let curData = sortedQstList[i];
        curData.valid_values = sortedQstValueList;
    }
}

// 转换为新的结果
const translate2newResult = function (result, resultNew) {
    let listDataArr = new Array(); // 返回的题目内容列表
    let dataArr = result.data; // new Array();//
    let len = getJsonLength(dataArr);
    let dataIndexDict = { "lastDataIndex": 0, "curQstDataIndex": [] };//用于记录上一个索引，和当前题目data_index集合
    for (let i = 0; i < len; i++) {
        let jumpDict = {};
        let curData = dataArr[i];
        let tmp = new Object();
        tmp.tid = curData.id; // 题目的计数序号，唯一但不用于提交，可在relation中使用
        tmp.page_id = curData.pageId; // 页码ID，提交问卷用
        tmp.title_id = curData.qid; // 题目id_每个问卷每个题目唯一标识，提交用
        tmp.title = tmp.title_id + curData.title; // 题目的标题，title_id + 标题字符串
        tmp.title_type = curData.srcType; // 题目类型_每个平台自己的题目类型_1_23
        tmp.sys_type = traslateType(curData.type, curData.srcType); // 内部平台题目类型
        tmp.name = curData.title; // 题目名称，给制单人看的
        tmp.value = ""; // 值 - 题目维度下不需要填
        tmp.is_jump = curData.hasJump; // 是否是跳题 "1" || True | ""
        if(curData.hasJump) {
            jumpDict = translate2JumpDict(curData.jumpData);
        }
        tmp.jump_to = null == curData.jumpData ? "" : curData.jumpData; // 跳到哪个题目 "" / title_id
        tmp.req = traslateRequired(curData.isRequired); // 是否必须题 "1" / "0" || ""
        tmp.is_text = isText(tmp); // 是否填空题 bool
        tmp.relation = curData.relation;
        tmp.min_oper_num = 0; // 最小值
        tmp.max_oper_num = 0; // 最大值
        setMaxAndMinIfExist(tmp, curData.range);
        tmp.rate = 0; // 权重 - 题目维度下不需要填
        tmp.text = ""; // 填空内容 - 题目维度下不需要填
        tmp.is_reverse = false; //是否反转 - 题目维度下不需要填
        tmp.options = [];
        tmp.children = [];
        if ("MATRIX" == tmp.sys_type || "MULTIPLE_MATRIX" == tmp.sys_type || "MATRIX_TEXT" == tmp.sys_type
            || "MULTIPLE_TEXT" == tmp.sys_type) { // 矩阵or多填题
            tmp.children = getChildren(curData, tmp, dataIndexDict);
        } else if ("TEXT" == tmp.sys_type || "AREA" == tmp.sys_type || "DATE" == tmp.sys_type) { // 填空类题型
            tmp.options.push(buildTextOption(tmp, dataIndexDict));
        } else if ("CASCADE_DROPDOWN" == tmp.sys_type) { // 级联下拉题
            tmp.options.push(buildCascadeOption(tmp, dataIndexDict, curData.srcQstData));
        } else {
            tmp.options = tanslateOptions(curData, tmp, dataIndexDict, jumpDict); // 选项
        }
        if("DESCRIPTION" != tmp.sys_type) {//描述类占位题不生成dataIndexDict值
            tmp.data_index = dataIndexDict["curQstDataIndex"]; // 数据库索引
        }
        tmp.is_repeat = false; // 是否去重 - 题目维度下不需要填 - 对于解析来说，默认false
        dataIndexDict["curQstDataIndex"] = [];

        listDataArr.push(tmp);
    }
    resultNew.list = modifyRealValueToRlValue(listDataArr);//相关分析需要删除real_value才能运行成功，故此处先将real_value替换成rl_value
    let dataIndexArr = getDataIndexArr(result);
    let newDataIndexArr = modifyRealValueToRlValue(dataIndexArr); // 相关分析需要删除real_value才能运行成功，故此处先将real_value替换成rl_value
    addValidValues(newDataIndexArr); // 增加valid_values字段
    resultNew.data_index = newDataIndexArr;
    resultNew.total_data_index = dataIndexDict["lastDataIndex"];
}

const fs = require('fs');
// const srcData = window.qsSrcData;
// 加载题目主体函数定义
const getDataArr = function (sdata_file) {
    // console.log("==================================== enter js ====================================");
    let sdata = "";
    try {
        const data = fs.readFileSync(sdata_file);
        // console.log(data.toString());
        sdata = data.toString();
    } catch (err) {
        console.error(err);
    }
    let srcData = str2json(sdata);

    let resultNew = { list: [], data_index: [], total_data_index: 0 };//list代表问卷的所有题目；data_index代表数据库对应的数据；
    var result = { title: '', error: '', data: [] };//error内容为加载失败消息：如问卷暂停、需微信登录等
    var dataArray = new Array(); // 返回的题目内容列表
    var logicDict4display = []; //显示逻辑映射字典{dstId:srcId}
    var counter = 0;
    var dslQstArr = new Array(); //DSL题目数组

    if (null != srcData.data.survey_dsl && 0 != srcData.data.survey_dsl.length) {
        dslQstArr = getDslQstArr(srcData.data.survey_dsl);
    }

    let isJumpExistent = false;//getJumpExistent(srcData.data.survey_rules.version);
    var questions = srcData.data.questions;
    var quesLen = getJsonLength(questions);
    for (var i = 0; i < quesLen; i++) {
        var tmp = new Object();
        tmp.pageId = questions[i].page_id;//srcData.data.pages[k].id; // 页码ID
        tmp.id = ++counter; // 全局题号 ，从1开始递增。 
        tmp.qid = questions[i].id; // 题目id（提交使用的ID）
        tmp.type = getType(questions[i]);  // 见typeName 定义 返回字符串
        tmp.srcType = questions[i].type; //题目原始类型
        tmp.range = getRange(questions[i]);
        tmp.relation = ''; //赋值关联项;见关联字符串定义(显示逻辑)
        tmp.hasJump = false;
        tmp.jumpData = null;
        tmp.inner = getOptions(questions[i]); // 选项数据。 见选项数据定义
        tmp.isRequired = getRequired(questions[i]); // 是否必选。
        tmp.title = cleanText(questions[i].title); // 题目标题，需要避免使用特殊字符“_”
        tmp.srcQstData = questions[i];

        //针对引用题处理
        if ("" != questions[i].refer && null != questions[i].refer) {
            tmp.type = "引用题目";
        }
        if (0 == tmp.inner.length && ('单选' == tmp.type || '多选' == tmp.type || '排序选择' == tmp.type)) {
            tmp.type = '占位题';
        }

        dataArray.push(tmp);

        if (getJsonLength(questions[i].options) > 0 && false == isJumpExistent) {//更新显示逻辑字典
            updateLogicDict4display(logicDict4display, questions[i].options, tmp.id);
        }
    }

    //更新跳转逻辑题号
    if (isJumpExistent) {
        updateSkipLogic(srcData.data.survey_rules, dataArray);
    }
    //注意：
    //1.腾讯问卷的逻辑规则是“显示逻辑”与“跳转逻辑”互斥。如需使用“全局跳转逻辑”，已设置的“显示逻辑”及“随机选题”设置将全部失效
    //2.编写显示逻辑时会提示：“切换到显示逻辑设置后，问卷现有的跳转逻辑设置将会失效”
    //如果不存在跳转逻辑，则更新显示逻辑题号
    if (!isJumpExistent) {
        updateDisplayLogic(logicDict4display, dataArray);
    }

    //更新DSL题
    updateDslQst(dslQstArr, dataArray);

    result.title = srcData.data.title;
    result.data = dataArray;

    translate2newResult(result, resultNew);
    return resultNew;// return result; //
};

// getDataArr(param1);//测试结果
console.log(JSON.stringify(getDataArr(param1)));//测试输出结果
